package com.example.utils;

import com.example.dto.UserDTO;

public class UserHolder {
    /**
     * UserHolder 是一个线程安全的用户上下文工具类，通过 ThreadLocal 实现每个线程独享用户信息，在多线程环境中实现用户数据的隔离与安全传递。
     */
    /**
     * 1. Web服务器的处理模型
     * 在 Java Web 应用中，常见的服务器（如 Tomcat、Jetty、Undertow）会使用 线程池 来处理客户端发来的请求：
     * 用户 A 发来一个请求，服务器分配一个线程来处理；
     * 用户 B 发来请求，也会由线程池分配另一个线程处理；
     * 这个线程是短暂绑定的：只在该请求处理过程中生效。
     * ⚠️ 所以：
     * 并不是“一个用户 = 一个线程”，而是“一次请求 = 一个线程”。
     * 2. ThreadLocal 和请求绑定
     * 虽然不是“一人一线程”，但由于“一次请求 = 一个线程”，我们可以通过 ThreadLocal：
     * 在请求刚开始（比如登录成功或 token 校验成功）时保存用户信息；
     * 在请求过程的任意位置使用 UserHolder.getUser() 获取用户；
     * 在请求结束时（如拦截器 afterCompletion()）清除用户信息。
     * 🚨 为什么强调清除（removeUser()）？
     * 因为很多服务器使用线程池，线程会被重复利用：
     * 如果你不调用 remove()，上一次请求的用户信息可能会残留在线程中！
     * 这会造成用户信息错乱，甚至泄露。
     */
    /**
     * 每个用户其实对应都是去找tomcat线程池中的一个线程来完成工作的， 使用完成后再进行回收，既然每个请求都是独立的
     * 所以在每个用户去访问我们的工程时，我们可以使用ThreadLocal来做到线程隔离，每个线程操作自己的一份数据。
     */
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();

    public static void saveUser(UserDTO user){
        tl.set(user);
    }

    public static UserDTO getUser(){
        return tl.get();
    }

    public static void removeUser(){
        tl.remove();
    }
}
